<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>原型和原型链</title>
  </head>
  <body>
    <script>
      /* 1. 原型：每个对象都有一个对应的Prototype属性，这个属性指向该对象的原型对象。
        2. 原型链：当访问一个对象的属性时，如果该对象本身没有这个属性，那么就会去它的原型对象中查找，如果原型对象也没有，那么就会去它的原型对象的原型对象中查找，以此类推，直到找到Object.prototype为止，这个查找的路径就叫做原型链。 */

      /*1. 在原型上添加方法
        function Person(name,age) {
            this.name = name;
            this.age = age;
        }

        Person.prototype.say = function () {
            // console.log(this) this就是实例对象
            console.log(this.age)
        }

        const p = new Person('zhangsan',18);
        p.say()
        console.log(p.__proto__ === Person.prototype) // true
        console.log(Person.prototype === Function.prototype) // false
        console.log(Person.__proto__ === Object.prototype) // false */

      /* 2. 构造函数的继承
       function Person(name, age) {
        this.name = name;
        this.age = age;
      }
      
      Person.prototype.say = function () {
        console.log(this.age);
      };

      function Student(score) {
        this.score = score;
      }
      const p = new Person("zhangsan", 18);
      Student.prototype = p;
      const stu = new Student(90);
      stu.say(); */

      /* 3.es6继承
      class Person {
        constructor(name, age) {
          this.name = name;
          this.age = age;
        }
         say() {
            console.log("我"+this.name+"今年"+this.age+"岁了")
        }
      }

      class Student extends Person {
        constructor(name, age, score) {
          super(name, age);
          this.score = score;
        }
      }

      const stu = new Student("zhangsan", 18, 90);
      stu.say(); */

      /* function Foo() {
        this.a = 1;
      }
      Foo.prototype.b = 2;

      const foo = new Foo();
      console.log(foo.hasOwnProperty("a"));  */ // true hasOwnProperty()检查的是自身的属性

      function Animal(name) {
        console.log("this-Animal",this)
        this.name = name;
      }

      Animal.prototype.speak = function () {
        console.log(`${this.name} makes a noise.`);
      };

      function Dog(name) {
        // Animal(name) // this指向是window 
        Animal.call(this, name); // this指向是Dog的实例对象
      }

    //   Dog.prototype = Object.create(Animal.prototype);
    //   Dog.prototype = Animal.prototype; // 直接赋值会导致原型的污染
      Dog.prototype.constructor = Dog;

      Dog.prototype.speak = function () {
        console.log(`${this.name} barks.`);
      };

    //   const dog = new Dog("Rex");
      const animal = new Animal("Generic Animal");
      console.log("animal",animal)
    //   dog.speak();
      console.log("dog",Dog.prototype)
      console.log("animal",Animal.prototype)

      // 
    </script>
  </body>
</html>
